#ifndef __ZEN_PIXMAP_HPP__
#define __ZEN_PIXMAP_HPP__

#include "../gl.hpp"

#define __ZEN_LOADER_PIX__
#define __ZEN_LOADER_BMP__
//#define __ZEN_LOADER_PNG__
//#define __ZEN_LOADER_TGA__

namespace zen {

	namespace video {

		class Pixmap {


			public:

				Pixmap();
				Pixmap(const Pixmap &other);
				Pixmap(GLuint width, GLuint height, GLuint depth = 1, GLenum format = GL_RGB);
				Pixmap(const std::string &fileName, GLenum allocFormat = 0);
				~Pixmap();

				Pixmap& operator = (const Pixmap &other);

				// Get pixmap attributes.
				GLuint getWidth() const  { return width; }
				GLuint getHeight() const { return height; }
				GLuint getDepth() const  { return depth; }
				GLenum getFormat() const { return format; }

				// Get pixels.
				GLubyte* getData() const { return data; }

				// Get bits per pixel.
				unsigned int formatBitCount() const  { return formatBitCount(this->format); };
				static unsigned int formatBitCount(GLenum format);

				// Returns true if pixmap contains no data.
				bool isEmpty() { return data == NULL; }

				// Load image data from a file, return true if successful, false if file doesn't exist, can't read or format not supported.
				bool load(const std::string &fileName, GLenum allocFormat = 0);

				// Save image data to a file, return true if successful, false if can't create file or format not supported.
				bool save(const std::string &fileName, GLenum saveFormat = 0) const;

				// Reallocates the image with a new size.
				bool realloc(GLuint width, GLuint height, GLuint depth = 1, GLenum format = GL_RGB);

				// Frees the data from memory.
				bool free();

				// Copies a pixmap.
				bool copy(const Pixmap &source);

				// Convert pixmap's format to another format, the defaultValue will be assigned to missing data (ex. alpha=defaultValue when RGB to RGBA).
				// Return true if successful.
				// Possible conversions:
				//      - RGB, BGR, RGBA, BGRA  ->  RGB, BGR, RGBA, BGRA;
				//      - LUMINANCE_ALPHA, LUMINANCE, ALPHA, RED, GREEN, BLUE  ->  LUMINANCE_ALPHA, LUMINANCE, ALPHA, RED, GREEN, BLUE.
				bool convert(GLenum format, GLubyte defaultValue = 255);

				// Color manipulation
				bool fill(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha = 255);
				bool setAlphaWhereColor(GLubyte newAlpha, GLubyte red, GLubyte green, GLubyte blue);
				bool setColorWhereAlpha(GLubyte newRed, GLubyte newGreen, GLubyte newBlue, GLubyte alpha);

				// Load a specific file format.
				#ifdef __ZEN_LOADER_PIX__ // Enclave Pixmap
				bool loadPIX(const std::string &fileName);
				bool savePIX(const std::string &fileName) const;
				#endif
				#ifdef __ZEN_LOADER_BMP__ // Windows Bitmap
				bool loadBMP(const std::string &fileName);
				bool saveBMP(const std::string &fileName) const;
				#endif
				#ifdef __ZEN_LOADER_PNG__
				bool loadPNG(const std::string &fileName);
				bool savePNG(const std::string &fileName) const;
				#endif
				#ifdef __ZEN_LOADER_TGA__ // Targa format
				bool loadTGA(const std::string &fileName);
				bool saveTGA(const std::string &fileName) const;
				#endif

			
			private:

				GLubyte* data;                  // Pointer to the image data.
				GLuint width, height, depth;    // Image dimensions.
				GLenum format;


		};

	} // namespace video

} // namespace zen

#endif // __ZEN_PIXMAP_HPP__
